package com.yanglei.client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import com.yanglei.util.CharacterUtil;
import com.yanglei.util.Random;
import com.yanglei.util.XMLUtil;

public class ClientConnection extends Thread {

	private String hostAddress;

	private int port;

	private String username;

	private ClientLogin clientlogin;

	private Socket socket;

	private InputStream is;

	private OutputStream os;

	private Client client;

	private Vector<String> vector = new Vector<String>();

	private singleClient singleClient;

	private FileInputStream fileInputStream;

	private FileOutputStream fileOutStream;

	private DataInputStream dateInputStream;

	private DataOutputStream dataOutStream;

	private String filePath;

	private int port1;

	private Map<String, singleClient> clientMap = new HashMap<String, singleClient>();

	public Map<String, singleClient> getClientMap() {
		return clientMap;
	}

	public Client getClient() {
		return client;
	}

	public int getPort1() {
		return port1;
	}

	public String getFilePath() {
		return filePath;
	}

	public FileInputStream getFileInputStream() {
		return fileInputStream;
	}

	public FileOutputStream getFileOutStream() {
		return fileOutStream;
	}

	public DataInputStream getDateInputStream() {
		return dateInputStream;
	}

	public DataOutputStream getDataOutStream() {
		return dataOutStream;
	}

	public String getUsername() {
		return username;
	}

	public singleClient getSingleClient() {
		return singleClient;
	}

	public ClientConnection(ClientLogin clientlogin, String hostAddress, int port2, String username) {
		this.clientlogin = clientlogin;
		this.hostAddress = hostAddress;
		this.port = port2;
		this.username = username;
		// 连接服务器
		this.connect2Server();
	}

	public Socket getSocket() {
		return socket;
	}

	// _B接服掌_
	private void connect2Server() {
		try {
			this.socket = new Socket(this.hostAddress, this.port);

			this.is = this.socket.getInputStream();

			this.os = this.socket.getOutputStream();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 用户登录 服务器发送用户名
	// 返回true 表示登陆成功
	// 返回false 表示登陆失败
	public boolean login() {
		try {
			String xml = XMLUtil.constructLoginXML(username);

			os.write(xml.getBytes());// 向服掌鞫税l送用户的登录信息

			byte[] buf = new byte[5000];
			int length = is.read(buf);// 读取服务器的响应信息

			String loginResultXML = new String(buf, 0, length);

			String loginResult = XMLUtil.extractLoginResult(loginResultXML);

			// 登陆成功
			if ("success".equals(loginResult)) {
				// 连接服务器成功后，打开聊天窗口
				this.client = new Client(this);

				this.clientlogin.getjFrame().setVisible(false);

				return true;
			}
			// 登陆失败
			else {
				return false;
			}

		} catch (Exception e) {
			// TODO: handle exception
		}
		return false;
	}

	@Override
	public void run() {
		try {
			while (true) {
				byte[] buf = new byte[5000];
				int length = is.read(buf);

				String xml = new String(buf, 0, length);

				// 得到xml数据中得type
				int type = Integer.parseInt(XMLUtil.extractType(xml));

				// 如果type=userlist
				// 在线用户列表

				if (type == CharacterUtil.USER_LIST) {
					vector = XMLUtil.extractUserList(xml);

					this.client.getDlm().clear();
					for (String s : vector)
						this.client.getDlm().addElement(s);
				}
				// 服务器端发来的消息
				else if (type == CharacterUtil.SERVER_MESSAGE) {
					String content = XMLUtil.extracContent(xml);

					this.client.getJta2().append(content + "\n");
				}
				// 关闭服务器窗口
				else if (type == CharacterUtil.CLOSE_SERVER_WINDOW) {
					JOptionPane.showMessageDialog(this.client.getJframe(), "服务器端已关闭，程序将退出", "信息",
							JOptionPane.ERROR_MESSAGE);
					System.exit(0);
				}
				// 服务器确认关闭客户端窗口
				else if (type == CharacterUtil.CLOSE_CLIENT_WINDOW_CONFIRMATION) {
					try {
						this.getSocket().getInputStream().close();
						this.getSocket().getOutputStream().close();
						this.getSocket().close();
					} catch (Exception e) {
						// TODO: handle exception
					} finally {
						System.exit(0);
					}

				}

				// 私聊请求信息
				else if (type == CharacterUtil.SINGLE_REQUEST) {
					// 得到请求者的名字
					String username = XMLUtil.extractUsername2(xml);
					int choose = JOptionPane.showConfirmDialog(this.client.getJframe(), username + "向你发起私聊请求", "新消息！",
							JOptionPane.INFORMATION_MESSAGE);

					// 同意后执行下面这段代码
					if (choose == 0) {
						// 初始化私聊窗口
						this.singleClient = new singleClient(this, username);
						clientMap.put(username, getSingleClient());
						// 返回确认信息
						this.sendSingleMessage("success", "11", username);
					} else {
						this.sendSingleMessage("error", "11", username);
					}
				}
				// 请求返回
				else if (type == CharacterUtil.SINGLE_RESPONCE) {
					// 请求接收者
					String username = XMLUtil.extractUsername2(xml);

					String content = XMLUtil.extracContent(xml);

					if (content.equals("success")) {
						JOptionPane.showMessageDialog(this.client.getJframe(), username + "接受了你的私聊请求", "新消息",
								JOptionPane.INFORMATION_MESSAGE);
						this.singleClient = new singleClient(this, username);
						clientMap.put(username, getSingleClient());
					} else {
						JOptionPane.showMessageDialog(this.client.getJframe(), username + "拒绝了你的私聊请求", "新消息",
								JOptionPane.ERROR_MESSAGE);
					}
				}
				// 服务器发来的私聊消息
				else if (type == CharacterUtil.SINGLE_CLIENT_SERVER) {
					String content = XMLUtil.extracContent(xml);
					String sendUsername = XMLUtil.extractUsername(xml);
					clientMap.get(sendUsername).getJtextarea().append(content + "\n");
				}
				// 服务器发来另一个私聊窗口关闭的消息
				else if (type == CharacterUtil.SINGLE_CLIENT_CLOSE) {
					String username = XMLUtil.extractUsername2(xml);

					JOptionPane.showMessageDialog(this.getSingleClient().getJframe(), username + "已退出私聊，该窗口即将关闭！", "警告",
							JOptionPane.ERROR_MESSAGE);

					// 施放私聊窗口的资源 关闭私聊窗口
					this.getSingleClient().getJframe().dispose();
					this.clientMap.remove(username);
				}
				// 踢人通知
				else if (type == CharacterUtil.REMOVE_CLIENT) {
					JOptionPane.showMessageDialog(this.client.getJframe(), "由于你的愚蠢行为，你被管理员踢出！该窗口即将关闭！", "严重",
							JOptionPane.ERROR_MESSAGE);
					System.exit(0);
				}
				// 自己不能与自己私聊
				else if (CharacterUtil.SAME_SINGLE_NAME == type) {
					JOptionPane.showMessageDialog(this.client.getJframe(), "自己不能与自己私聊", "错误",
							JOptionPane.ERROR_MESSAGE);
					this.client.setSingleName("");
				}
				// 文件传输请求
				else if (CharacterUtil.SEND_FILE_REQUEST == type) {

					// 发送文件传输请求的一方
					String sendUsername = XMLUtil.extractUsername2(xml);

					// 即将发送的文件的名字
					String fileName = XMLUtil.extracContent(xml);

					JFileChooser file = new JFileChooser();
					int i = JOptionPane.showConfirmDialog(this.getSingleClient().getJframe(),
							sendUsername + "向你发来一个文件，" + fileName + "是否接受？", "新消息", JOptionPane.INFORMATION_MESSAGE);
					if (i == 0) {
						int resule = file.showSaveDialog(this.getSingleClient().getJframe());
						if (resule == file.APPROVE_OPTION) {
							fileName = file.getSelectedFile().getName();

							filePath = file.getSelectedFile().getPath().replace("\\", "/");
							int t = JOptionPane.showConfirmDialog(null, fileName, "确认要保存的文件", JOptionPane.YES_OPTION);
							if (t == 0) {

								port1 = Random.getRandom();
								String message = "success";
								String Port = "" + port1;
								this.sendFileMessage(message, "16", sendUsername, Port,
										Inet4Address.getLocalHost().toString().split("/")[1]);
								// 打开文件接收线程
								ClienReceiveFileThread cft = new ClienReceiveFileThread(this, this.port1);
								cft.start();
							}

						}

					} else {
						this.sendSingleMessage("error", "16", sendUsername);
					}
				}
				// 文件传输回复信息
				else if (CharacterUtil.SEND_FILE_RESPONSE == type) {
					String username = XMLUtil.extractUsername2(xml);

					String content = XMLUtil.extracContent(xml);
					if (content.equals("success")) {
						JOptionPane.showMessageDialog(this.getSingleClient().getJframe(), username + "接受了你的传输请求", "新消息",
								JOptionPane.INFORMATION_MESSAGE);

						String port = XMLUtil.extractPort(xml);
						String address = XMLUtil.extractAddress(xml);

						System.out.println(address);
						// 打开文件输入流
						ClientSendFileThread csft = new ClientSendFileThread(this, Integer.parseInt(port), address);
						csft.start();

					} else {
						JOptionPane.showMessageDialog(this.getSingleClient().getJframe(), username + "拒绝了你的传输请求", "新消息",
								JOptionPane.ERROR_MESSAGE);
					}
				}

			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void sendMenssage(String message, String type) {
		try {
			int t = Integer.parseInt(type);

			String xml = null;

			// 把客户端向服务器发送聊天数据 组装成xml数据
			if (CharacterUtil.CLIENT_MESSAGE == t) {
				xml = XMLUtil.constructMessageXML(username, message);
			}
			// 客户端向服务器发送关闭窗口的消息
			else if (CharacterUtil.CLOSE_CLIENT_WINDOW == t) {
				xml = XMLUtil.constructCloseClientWindowXML(this.username);
			}

			// 向服务器发送数据
			this.os.write(xml.getBytes());

		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	// 私聊信息专用方法
	public void sendSingleMessage(String message, String type, String username) {
		try {
			int t = Integer.parseInt(type);

			String xml = null;
			// 向服务器发送私聊信息
			if (CharacterUtil.SINGLE_CLIENT_SERVER == t) {
				xml = XMLUtil.constructSingleClientServer(message, this.getUsername(), username);
			}
			// 私聊请求
			else if (CharacterUtil.SINGLE_REQUEST == t) {
				xml = XMLUtil.construcSingleRequestXML(username, this.getUsername());

			}
			// 私聊返回
			else if (CharacterUtil.SINGLE_RESPONCE == t) {
				// username 发送请求的用户名
				xml = XMLUtil.construcSingleResponseXML(message, username, getUsername());
			}
			// 私聊窗口关闭
			else if (CharacterUtil.SINGLE_CLIENT_CLOSE == t) {
				xml = XMLUtil.constructCloseSingleClientWindowXML(username, this.username);
			}
			// 发送文件请求
			else if (CharacterUtil.SEND_FILE_REQUEST == t) {
				xml = XMLUtil.construcFileRequestXML(username, this.getUsername(),
						this.getSingleClient().getFileName());
			}

			this.os.write(xml.getBytes());
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	public void sendFileMessage(String message, String type, String username, String port, String address) {
		try {
			int t = Integer.parseInt(type);

			String xml = null;

			// 发送文件请求回复
			if (CharacterUtil.SEND_FILE_RESPONSE == t) {
				xml = XMLUtil.construcSendFileResponseXML(message, username,
						this.getSingleClient().getClientConnection().getUsername(), port, address);
			}
			this.os.write(xml.getBytes());
		} catch (Exception e) {
			// TODO: handle exception
		}

	}
}
